/**
 * @file rm_referee.C
 * @author kidneygood (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-11-18
 *
 * @copyright Copyright (c) 2022
 *
 */

#include "referee.h"
#include "crc_rm.h"
#include "referee_protocol.h"
#include "robotdef.h"
#include "rttypes.h"
#include <stdint.h>
 
#define LOG_TAG "referee"
#define LOG_LVL LOG_LVL_DBG
#include <ulog.h>

static referee_info_t referee_info;			  // 裁判系统数据
rt_tick_t last_recv_timestamp = 0; // 新增变量，用于记录上一次接收时间戳
 /**
  * @brief  读取裁判数据,中断中读取保证速度
  * @param  buff: 读取到的裁判系统原始数据
  * @retval 是否对正误判断做处理
  * @attention  在此判断帧头和CRC校验,无误再写入数据，不重复判断帧头
  */
void JudgeReadData(uint8_t *buff)
 {
     uint16_t judge_length; // 统计一帧数据长度
     if (buff == RT_NULL)	   // 空数据包，则不作任何处理
         return;
 
     // 写入帧头数据(5-byte),用于判断是否开始存储裁判数据
     rt_memcpy(&referee_info.FrameHeader, buff, LEN_HEADER);
 
     // 判断帧头数据(0)是否为0xA5
     if (buff[SOF] == REFEREE_SOF)
     {
         // 帧头CRC8校验
         if (Verify_CRC8_Check_Sum(buff, LEN_HEADER) == RM_TRUE)
         {
             // 统计一帧数据长度(byte),用于CR16校验
             judge_length = buff[DATA_LENGTH] + LEN_HEADER + LEN_CMDID + LEN_TAIL;
             // 帧尾CRC16校验
             if (Verify_CRC16_Check_Sum(buff, judge_length) == RM_TRUE)
             {
                 referee_info.init_flag=1;
                 // 2个8位拼成16位int
                 referee_info.CmdID = (buff[6] << 8 | buff[5]);
                 // 解析数据命令码,将数据拷贝到相应结构体中(注意拷贝数据的长度)
                 // 第8个字节开始才是数据 data=7
                 switch (referee_info.CmdID)
                 {
                 case ID_game_state: // 0x0001
                    rt_memcpy(&referee_info.GameState, (buff + DATA_Offset), LEN_game_state);
                     break;
                //  case ID_game_result: // 0x0002
                //     rt_memcpy(&referee_info.GameResult, (buff + DATA_Offset), LEN_game_result);
                //      break;
                //  case ID_game_robot_survivors: // 0x0003
                //     rt_memcpy(&referee_info.GameRobotHP, (buff + DATA_Offset), LEN_game_robot_HP);
                //      break;
                //  case ID_event_data: // 0x0101
                //     rt_memcpy(&referee_info.EventData, (buff + DATA_Offset), LEN_event_data);
                //      break;
                //  case ID_supply_projectile_action: // 0x0102
                //  rt_memcpy(&referee_info.SupplyProjectileAction, (buff + DATA_Offset), LEN_supply_projectile_action);
                //      break;
                 case ID_game_robot_state: // 0x0201
                 rt_memcpy(&referee_info.GameRobotState, (buff + DATA_Offset), LEN_game_robot_state);
                     break;
                 case ID_power_heat_data: // 0x0202
                 rt_memcpy(&referee_info.PowerHeatData, (buff + DATA_Offset), LEN_power_heat_data);
                     break;
                //  case ID_game_robot_pos: // 0x0203
                //  rt_memcpy(&referee_info.GameRobotPos, (buff + DATA_Offset), LEN_game_robot_pos);
                //      break;
                //  case ID_buff_musk: // 0x0204
                //  rt_memcpy(&referee_info.BuffMusk, (buff + DATA_Offset), LEN_buff_musk);
                //      break;
                //  case ID_aerial_robot_energy: // 0x0205
                //  rt_memcpy(&referee_info.AerialRobotEnergy, (buff + DATA_Offset), LEN_aerial_robot_energy);
                //      break;
                //  case ID_robot_hurt: // 0x0206
                //  rt_memcpy(&referee_info.RobotHurt, (buff + DATA_Offset), LEN_robot_hurt);
                //     break;
                //  case ID_shoot_data: // 0x0207
                //  rt_memcpy(&referee_info.ShootData, (buff + DATA_Offset), LEN_shoot_data);
                //     break;
                //  case ID_shoot_remaining:
                //  rt_memcpy(&referee_info.ext_shoot_remaing, (buff + DATA_Offset), LEN_shoot_remaing);
                //     break;
                //  case ID_rfid_status:
                //  rt_memcpy(&referee_info.rfid_status, (buff + DATA_Offset), LEN_rfid_status);
                //     break;
                 }
             }
         }
         // 首地址加帧长度,指向CRC16下一字节,用来判断是否为0xA5,从而判断一个数据包是否有多帧数据
         if (*(buff + sizeof(xFrameHeader) + LEN_CMDID + referee_info.FrameHeader.DataLength + LEN_TAIL) == 0xA5)
         { // 如果一个数据包出现了多帧数据,则再次调用解析函数,直到所有数据包解析完毕
             JudgeReadData(buff + sizeof(xFrameHeader) + LEN_CMDID + referee_info.FrameHeader.DataLength + LEN_TAIL);
         }
     }
 }
 
 /**
  * @brief 裁判系统数据发送函数
  * @param
  */
void RefereeSend(uint8_t *send, uint16_t tx_len)
{

}

// 读取裁判系统数据的函数
void read_referee_powerinfo(float* chassis_max_power,float* buffer_energy) {
    // 将 uint16_t 类型的数据转换为 float 类型
    if (chassis_max_power != RT_NULL) {
        *chassis_max_power = (float)referee_info.GameRobotState.chassis_power_limit;
    }
    if (buffer_energy != RT_NULL) {
        *buffer_energy = (float)referee_info.PowerHeatData.buffer_energy;
    }
}

void read_referee_robot_hp(float* robot_hp,rt_uint8_t* hurt_type){
    if (robot_hp !=RT_NULL) {*robot_hp = (float)referee_info.GameRobotState.current_HP;}
    if (hurt_type !=RT_NULL) {*hurt_type = (rt_uint8_t)referee_info.RobotHurt.hurt_type;}
}

rt_uint8_t read_referee_game_progress(void)
{
    return referee_info.GameState.game_progress;
}

// 地盘发送消息用
void chassis_to_gimbal(Chassis_Upload_Data_s *Chassis_Upload_Data)
{
    if (referee_info.init_flag == 1) 
    {
        Chassis_Upload_Data->current_hp_percent = referee_info.GameRobotState.current_HP;
        if (referee_info.GameState.game_progress==4) {Chassis_Upload_Data->game_progress =1;}else{Chassis_Upload_Data->game_progress =0;}
        Chassis_Upload_Data->power_management_chassis_output = referee_info.GameRobotState.power_management_chassis_output;
        Chassis_Upload_Data->power_management_gimbal_output = referee_info.GameRobotState.power_management_gimbal_output;
        Chassis_Upload_Data->power_management_shooter_output = referee_info.GameRobotState.power_management_shooter_output;
                
        // 提取第 23 位（中心增益点）
        rt_uint32_t rfid_status = referee_info.rfid_status.rfid_status;

        rt_uint8_t center_gain_point = (rfid_status >> 23) & 0x01;
        Chassis_Upload_Data->event_center_aera_rmul = center_gain_point;
        
        // 提取第 19 位（己方与兑换区不重叠的补给区/RMUL补给区）
        rt_uint8_t supply_area_rmul = (rfid_status >> 19) & 0x01;
        Chassis_Upload_Data->event_supply_area_rmul =supply_area_rmul;
        Chassis_Upload_Data->event_supply_area_rmuc =supply_area_rmul;

        Chassis_Upload_Data->shooter_17mm_1_barrel_heat = referee_info.PowerHeatData.shooter_17mm_1_barrel_heat;
        Chassis_Upload_Data->shooter_17mm_2_barrel_heat = referee_info.PowerHeatData.shooter_17mm_2_barrel_heat;
    }
}
 